package com.nanrui.mutualinductor.ui.page;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.Intent;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;

import com.batman.baselibrary.base.BaseActivity;
import com.batman.baselibrary.utils.ToastUtils;
import com.clj.fastble.BleManager;
import com.clj.fastble.callback.BleGattCallback;
import com.clj.fastble.callback.BleIndicateCallback;
import com.clj.fastble.callback.BleNotifyCallback;
import com.clj.fastble.callback.BleReadCallback;
import com.clj.fastble.callback.BleScanCallback;
import com.clj.fastble.callback.BleWriteCallback;
import com.clj.fastble.data.BleDevice;
import com.clj.fastble.exception.BleException;
import com.clj.fastble.scan.BleScanRuleConfig;
import com.clj.fastble.utils.HexUtil;
import com.network.utils.LogUtils;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public abstract class MyBlueBleActivity extends BaseActivity {


    private final int REQUEST = 999;
    private String mMac;

    private List<BleDevice> mScanResultList = new ArrayList<>();
    private List<String> mMacList = new ArrayList<>();
    private List<String> mMacListRead = new ArrayList<>();


    protected void scan() {
        if (BleManager.getInstance().isSupportBle()) {
            setScanRule();
            BleManager.getInstance().scan(new BleScanCallback() {
                @Override
                public void onScanStarted(boolean success) {

                }

                @Override
                public void onScanning(BleDevice bleDevice) {

                }

                @Override
                public void onScanFinished(List<BleDevice> scanResultList) {
                    for (BleDevice bleDevice :
                            scanResultList) {

                        if (!mMacList.contains(bleDevice.getMac())) {
                            mMacList.add(bleDevice.getMac());
                            mScanResultList.add(bleDevice);
                        }
                    }

                    for (String macAddrese :
                            mMacList) {

                        Log.d("scanResultList",
                                macAddrese);
                    }

                }
            });
        } else {
            ToastUtils.showLong("您的设备不支持蓝牙");
        }
    }

    private void openBlutooh() {

        if (BleManager.getInstance().isBlueEnable()) {
            startConnect(mMac);
        } else {
            ToastUtils.showLong("请打开您的蓝牙");
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(intent, REQUEST);
        }
    }

    private void setScanRule() {

        UUID[] serviceUuids = null;
        BleScanRuleConfig scanRuleConfig = new BleScanRuleConfig.Builder()
                .setServiceUuids(serviceUuids)      // 只扫描指定的服务的设备，可选
                .setDeviceName(true, "")   // 只扫描指定广播名的设备，可选
                .setDeviceMac("")                  // 只扫描指定mac的设备，可选
                .setAutoConnect(false)      // 连接时的autoConnect参数，可选，默认false
                .setScanTimeOut(10 * 1000)              // 扫描超时时间，可选，默认10秒
                .build();
        BleManager.getInstance().initScanRule(scanRuleConfig);
    }

//    private LoadingDialog mLoadingDialog;

    private void showDialog() {

//        String message = "";
//        message = "正在为您落锁，请耐心等待";
//        mLoadingDialog = DialogHelper.getWaitDialog(getActivity(), message);
//        mLoadingDialog.show();
    }

    private void dismissDialog() {

//        if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
//            mLoadingDialog.dismiss();
//        }
    }


    /**
     * 通过Mac连接
     *
     * @param mac
     */
    private void startConnect(String mac) {

        if (TextUtils.isEmpty(mac)) {
            ToastUtils.showLong("操作失败,未发现蓝牙");
            return;
        }
        showDialog();
        if (!BleManager.getInstance().isConnected(mac)) {
            BleManager.getInstance().connect(mac, new BleGattCallback() {
                @Override
                public void onStartConnect() {
                    // 开始连接
                    LogUtils.d(TAG, "开始连接");
//                    times = 1;
                }

                @Override
                public void onConnectFail(BleDevice bleDevice, BleException exception) {
                    // 连接失败
                    LogUtils.d(TAG, "连接失败");
//                    times++;
//                    if (times == 3) {
//                    ToastUtils.showLong("操作失败");
                    dismissDialog();
//                    }
                }

                @Override
                public void onConnectSuccess(final BleDevice bleDevice, final BluetoothGatt gatt, int s) {
                    // 连接成功，BleDevice即为所连接的BLE设备
                    LogUtils.d(TAG, "连接成功");

                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            operation(bleDevice, gatt);
                        }
                    }, 200);

                }

                @Override
                public void onDisConnected(boolean isActiveDisConnected, BleDevice bleDevice, BluetoothGatt gatt, int status) {
                    // 连接中断，isActiveDisConnected表示是否是主动调用了断开连接方法
                    LogUtils.d(TAG, "连接中断");
//                    ToastUtils.showLong("操作失败");
                    dismissDialog();
                    mWriteBleDevice = null;
                    mNotifyBleDevice = null;
                }
            });

        } else {
            //已经连接上
            BleDevice currentBleDevice = null;
            List<BleDevice> bleDevices = BleManager.getInstance().getAllConnectedDevice();
            for (BleDevice bleDevice :
                    bleDevices) {
                if (bleDevice.getMac().equalsIgnoreCase(mac)) {
                    currentBleDevice = bleDevice;
                    break;
                }
            }

            if (currentBleDevice == null) {
                return;
            }

            BluetoothGatt gatt = BleManager.getInstance().getBluetoothGatt(currentBleDevice);
            operation(currentBleDevice, gatt);
        }
    }

    private void operation(final BleDevice bleDevice, final BluetoothGatt gatt) {

        if (mNotifyBleDevice != null && mWriteBleDevice != null) {
            write(bleDevice, mWriteServiceUUID, mWriteCharacteristicUUID);
        } else {
            List<BluetoothGattService> serviceList = gatt.getServices();
            for (BluetoothGattService service : serviceList) {
//                UUID uuid_service = service.getUuid();

                List<BluetoothGattCharacteristic> characteristicList = service.getCharacteristics();
                for (BluetoothGattCharacteristic characteristic : characteristicList) {
                    final UUID uuid_chara = characteristic.getUuid();
                    final UUID uuid_service = characteristic.getService().getUuid();
                    LogUtils.d(TAG, "service " + uuid_service + " chara " + uuid_chara);
//                if (support(characteristic)) {
//                    notifyDevice(bleDevice, uuid_service.toString(), uuid_chara.toString());
//                } else {
//            }
                    int charaProp = characteristic.getProperties();

                    if ((charaProp & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
                        notifyDevice(bleDevice, uuid_service.toString(), uuid_chara.toString());
                    }

                    if ((charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) > 0) {

                        new Handler().postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                write(bleDevice, uuid_service.toString(), uuid_chara.toString());
                            }
                        }, 200);
                    }

                }


            }
        }
    }

    private void write(final BleDevice bleDevice, final String uuid_service, final String uuid_characteristic_write) {
        String result = "";
        byte[] request = result.getBytes();
        writeData(bleDevice, uuid_service, uuid_characteristic_write, request);

    }

    private boolean support(BluetoothGattCharacteristic characteristic) {

        boolean isSupport = false;
        StringBuilder property = new StringBuilder();
        int charaProp = characteristic.getProperties();
        if ((charaProp & BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
            property.append("Read");
            property.append(" , ");
        }
        if ((charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {
            property.append("Write");
            property.append(" , ");
        }
        if ((charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) > 0) {
            property.append("Write No Response");
            property.append(" , ");
        }
        if ((charaProp & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
            property.append("Notify");
            property.append(" , ");
        }
        if ((charaProp & BluetoothGattCharacteristic.PROPERTY_INDICATE) > 0) {
            property.append("Indicate");
            property.append(" , ");
        }
        if (property.length() > 1) {
            property.delete(property.length() - 2, property.length() - 1);
        }

        if (property.length() > 0) {
            if (property.toString().contains("Write") && (property.toString().contains("Notify") || property.toString().contains("Indicate"))) {
                isSupport = true;
            }
        }

        return isSupport;
    }

    private BleDevice mNotifyBleDevice;
    private String mNotifyServiceUUID;
    private String mNotifyCharacteristicUUID;

    private void notifyDevice(final BleDevice bleDevice, final String uuid_service, final String uuid_characteristic_notify) {
        BleManager.getInstance().notify(
                bleDevice,
                uuid_service,
                uuid_characteristic_notify,
                new BleNotifyCallback() {
                    @Override
                    public void onNotifySuccess() {
                        // 打开通知操作成功
                        LogUtils.d(TAG, uuid_characteristic_notify + "打开通知操作成功");
                        mNotifyBleDevice = bleDevice;
                        mNotifyServiceUUID = uuid_service;
                        mNotifyCharacteristicUUID = uuid_characteristic_notify;

                    }

                    @Override
                    public void onNotifyFailure(BleException exception) {
                        // 打开通知操作失败
                        LogUtils.d(TAG, uuid_characteristic_notify + "打开通知操作失败");
//                        ToastUtils.makeLongText(getActivity(), "操作失败");
                    }

                    @Override
                    public void onCharacteristicChanged(byte[] data) {
                        // 打开通知后，设备发过来的数据将在这里出现
//                        String s = HexUtil.formatHexString(data, true);

                        try {
                            dismissDialog();
                            String s = new String(data, "UTF-8");
                            LogUtils.d(TAG, uuid_characteristic_notify + "设备发过来的数据将在这里出现 " + s);
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }

                    }
                });

    }

    private void indicateDevice(final BleDevice bleDevice, final String uuid_service, final String uuid_characteristic_notify) {
//        mbleDevice = bleDevice;
//        muuid_service = uuid_service;
//        muuid_characteristic_notify = uuid_characteristic_notify;
        BleManager.getInstance().indicate(
                bleDevice,
                uuid_service,
                uuid_characteristic_notify,
                new BleIndicateCallback() {
                    @Override
                    public void onIndicateSuccess() {
                        LogUtils.d(TAG, uuid_characteristic_notify + "打开通知操作成功");
                    }

                    @Override
                    public void onIndicateFailure(BleException exception) {
                        LogUtils.d(TAG, uuid_characteristic_notify + "打开通知操作失败");
                    }

                    @Override
                    public void onCharacteristicChanged(byte[] data) {
                        String s = HexUtil.formatHexString(data, true);
                        LogUtils.d(TAG, uuid_characteristic_notify + "设备发过来的数据将在这里出现 " + s);
                    }
                });

    }

    private void readData(BleDevice bleDevice, final String uuid_service, final String uuid_characteristic_read) {

        BleManager.getInstance().read(
                bleDevice,
                uuid_service,
                uuid_characteristic_read,
                new BleReadCallback() {
                    @Override
                    public void onReadSuccess(byte[] data) {
                        // 读特征值数据成功
                        String s = HexUtil.formatHexString(data, true);
                        LogUtils.d(TAG, uuid_characteristic_read + "读特征值数据成功" + s);
                    }

                    @Override
                    public void onReadFailure(BleException exception) {
                        // 读特征值数据失败
                        LogUtils.d(TAG, uuid_characteristic_read + "读特征值数据失败");
                    }
                });
    }


    private BleDevice mWriteBleDevice;
    private String mWriteServiceUUID;
    private String mWriteCharacteristicUUID;

    private void writeData(final BleDevice bleDevice, final String uuid_service, final String uuid_characteristic_write, byte[] data) {
        BleManager.getInstance().write(
                bleDevice,
                uuid_service,
                uuid_characteristic_write,
                data,
                new BleWriteCallback() {
                    @Override
                    public void onWriteSuccess(int current, int total, byte[] justWrite) {
                        // 发送数据到设备成功
                        LogUtils.d(TAG, uuid_characteristic_write + "发送数据到设备成功");
                        mWriteBleDevice = bleDevice;
                        mWriteServiceUUID = uuid_service;
                        mWriteCharacteristicUUID = uuid_characteristic_write;
                    }

                    @Override
                    public void onWriteFailure(BleException exception) {
                        // 发送数据到设备失败
                        LogUtils.d(TAG, uuid_characteristic_write + "发送数据到设备失败");
                        ToastUtils.showLong("操作失败");
                        dismissDialog();
                    }
                });
    }
}
